#include "brick.h"

// 砖块颜色定义（从上到下：红、橙、黄、绿、青、蓝）
const uint16_t Brick::BRICK_COLORS[6] = {
  TFT_RED,
  TFT_ORANGE,
  TFT_YELLOW,
  TFT_GREEN,
  TFT_CYAN,
  TFT_BLUE
};

// ========== 初始化与绘制函数 ==========

// 初始化游戏
void Brick::initGame() {
  // 初始化挡板位置（居中）
  paddleX = (TFT_WIDTH - PADDLE_WIDTH) / 2;

  // 初始化球的位置（在挡板上方）
  ballX = paddleX + PADDLE_WIDTH / 2;
  ballY = PADDLE_Y - BALL_SIZE - 1;
  ballVX = 0;
  ballVY = 0;

  // 初始化砖块
  for (int row = 0; row < BRICK_ROWS; row++) {
    for (int col = 0; col < BRICK_COLS; col++) {
      bricks[row][col] = row + 1;  // 1-6对应不同颜色
    }
  }

  // 初始化游戏数据
  score = 0;  // 初始分数
  lives = 3;  // 初始生命值
  bricksRemaining = BRICK_ROWS * BRICK_COLS;
  state = READY;

  lastUpdateTime = millis();
}

// 绘制游戏区域边框
void Brick::drawGameArea(Screen &screen) {
  // 绘制顶部边框
  screen.spr.drawLine(BORDER_X, BORDER_Y, TFT_WIDTH - 1, BORDER_Y, TFT_WHITE);
  // 绘制左右边框
  screen.spr.drawLine(BORDER_X, BORDER_Y, BORDER_X, TFT_HEIGHT - 1, TFT_WHITE);
  screen.spr.drawLine(TFT_WIDTH - 1, BORDER_Y, TFT_WIDTH - 1, TFT_HEIGHT - 1, TFT_WHITE);
}

// 绘制挡板
void Brick::drawPaddle(Screen &screen) {
  screen.spr.fillRoundRect(paddleX, PADDLE_Y, PADDLE_WIDTH, PADDLE_HEIGHT, 2, TFT_CYAN);
}

// 绘制球
void Brick::drawBall(Screen &screen) {
  screen.spr.fillCircle((int)ballX, (int)ballY, BALL_SIZE / 2, TFT_WHITE);
}

// 绘制砖块
void Brick::drawBricks(Screen &screen) {
  for (int row = 0; row < BRICK_ROWS; row++) {
    for (int col = 0; col < BRICK_COLS; col++) {
      if (bricks[row][col] > 0) {
        int x = BRICK_OFFSET_X + col * (BRICK_WIDTH + BRICK_PADDING);
        int y = BRICK_OFFSET_Y + row * (BRICK_HEIGHT + BRICK_PADDING);
        uint16_t color = BRICK_COLORS[bricks[row][col] - 1];
        screen.spr.fillRoundRect(x, y, BRICK_WIDTH, BRICK_HEIGHT, 2, color);
      }
    }
  }
}

// 绘制游戏信息
void Brick::drawInfo(Screen &screen) {
  screen.spr.setTextColor(TFT_WHITE, TFT_BLACK);
  screen.spr.setTextDatum(TL_DATUM);

  // 分数
  screen.spr.drawString("分数:", INFO_X, INFO_Y, 2);
  screen.spr.fillRect(INFO_X, INFO_V_Y, 60, 16, TFT_BLACK);
  screen.spr.drawNumber(score, INFO_X, INFO_V_Y, 2);

  // 生命值
  screen.spr.drawString("生命值:", LIVES_X, LIVES_Y, 2);
  screen.spr.fillRect(LIVES_X, LIVES_V_Y, 60, 16, TFT_BLACK);
  screen.spr.drawNumber(lives, LIVES_X, LIVES_V_Y, 2);
}

// 绘制准备状态提示
void Brick::drawReadyMessage(Screen &screen) {
  screen.spr.setTextColor(TFT_YELLOW, TFT_BLACK);
  screen.spr.setTextDatum(CC_DATUM);
  screen.spr.drawString("按 O 键启动", TFT_WIDTH / 2, TFT_HEIGHT / 2 + 20, 2);
  screen.spr.drawString("左/右: 移动", TFT_WIDTH / 2, TFT_HEIGHT / 2 + 40, 1);
  screen.spr.drawString("A: 暂停 X: 退出", TFT_WIDTH / 2, TFT_HEIGHT / 2 + 60, 1);
  screen.spr.setTextDatum(TL_DATUM);
}

// 绘制暂停提示
void Brick::drawPausedMessage(Screen &screen) {
  screen.spr.fillRect(40, TFT_HEIGHT / 2, 160, 80, TFT_DARKGREY);
  screen.spr.drawRect(40, TFT_HEIGHT / 2, 160, 80, TFT_WHITE);
  screen.spr.setTextColor(TFT_YELLOW, TFT_DARKGREY);
  screen.spr.setTextDatum(CC_DATUM);
  screen.spr.drawString("暂停", TFT_WIDTH / 2, TFT_HEIGHT / 2, 4);
  screen.spr.setTextColor(TFT_WHITE, TFT_DARKGREY);
  screen.spr.drawString("按 A 键继续", TFT_WIDTH / 2, TFT_HEIGHT / 2 + 30, 2);
  screen.spr.setTextDatum(TL_DATUM);
}

// 绘制游戏结束界面
void Brick::drawGameOver(Screen &screen) {
  screen.spr.fillRect(40, TFT_HEIGHT / 2, 160, 100, TFT_RED);
  screen.spr.drawRect(40, TFT_HEIGHT / 2, 160, 100, TFT_WHITE);
  screen.spr.setTextColor(TFT_WHITE, TFT_RED);
  screen.spr.setTextDatum(CC_DATUM);
  screen.spr.drawString("游戏结束", TFT_WIDTH / 2, TFT_HEIGHT / 2 + 20, 4);
  screen.spr.drawString("分数: " + String(score), TFT_WIDTH / 2, TFT_HEIGHT / 2 + 40, 2);
  screen.spr.drawString("B: 重试 X: 退出", TFT_WIDTH / 2, TFT_HEIGHT / 2 + 60, 2);
  screen.spr.setTextDatum(TL_DATUM);
}

// 绘制胜利界面
void Brick::drawWin(Screen &screen) {
  screen.spr.fillRect(40, TFT_HEIGHT / 2, 160, 100, TFT_DARKGREEN);
  screen.spr.drawRect(40, TFT_HEIGHT / 2, 160, 100, TFT_WHITE);
  screen.spr.setTextColor(TFT_YELLOW, TFT_DARKGREEN);
  screen.spr.setTextDatum(CC_DATUM);
  screen.spr.drawString("你赢了", TFT_WIDTH / 2, TFT_HEIGHT / 2 + 20, 4);
  screen.spr.drawString("分数: " + String(score), TFT_WIDTH / 2, TFT_HEIGHT / 2 + 40, 2);
  screen.spr.drawString("B: 重试 X: 退出", TFT_WIDTH / 2, TFT_HEIGHT / 2 + 60, 2);
  screen.spr.setTextDatum(TL_DATUM);
}

// ========== 游戏逻辑函数 ==========

// 移动挡板
void Brick::movePaddle(int direction) {
  if (direction < 0) {
    // 左移
    paddleX -= PADDLE_SPEED;
    if (paddleX < 1) {
      paddleX = 1;
    }
  } else if (direction > 0) {
    // 右移
    paddleX += PADDLE_SPEED;
    if (paddleX > TFT_WIDTH - PADDLE_WIDTH - 1) {
      paddleX = TFT_WIDTH - PADDLE_WIDTH - 1;
    }
  }

  // 如果球还在挡板上（准备状态），球跟着挡板移动
  if (state == READY) {
    ballX = paddleX + PADDLE_WIDTH / 2;
  }
}

// 发射球
void Brick::launchBall() {
  if (state == READY) {
    state = PLAYING;
    // 设置球的初始速度（向上且稍微向右）
    ballVX = BALL_SPEED * 0.5;
    ballVY = -BALL_SPEED;
  }
}

// 移动球
void Brick::moveBall() {
  ballX += ballVX;
  ballY += ballVY;
}

// 检查球与边界的碰撞
void Brick::checkBallCollision() {
  // 左右边界
  if (ballX - BALL_SIZE / 2 <= 1 || ballX + BALL_SIZE / 2 >= TFT_WIDTH - 1) {
    ballVX = -ballVX;
    // 确保球在边界内
    if (ballX - BALL_SIZE / 2 <= 1) {
      ballX = 1 + BALL_SIZE / 2;
    } else {
      ballX = TFT_WIDTH - 1 - BALL_SIZE / 2;
    }
  }

  // 上边界
  if (ballY - BALL_SIZE / 2 <= TOP_BORDER_Y) {
    ballVY = -ballVY;
    ballY = TOP_BORDER_Y + BALL_SIZE / 2;
  }

  // 下边界（失去一条生命）
  if (ballY - BALL_SIZE / 2 >= TFT_HEIGHT) {
    lives--;
    if (lives > 0) {
      resetBall();
    } else {
      state = GAME_OVER;
    }
  }
}

// 检查球与挡板的碰撞
void Brick::checkPaddleCollision() {
  // 简单的矩形碰撞检测
  if (ballY + BALL_SIZE / 2 >= PADDLE_Y && ballY + BALL_SIZE / 2 <= PADDLE_Y + PADDLE_HEIGHT && ballX >= paddleX && ballX <= paddleX + PADDLE_WIDTH && ballVY > 0) {  // 只在球向下时反弹

    ballVY = -ballVY;
    ballY = PADDLE_Y - BALL_SIZE / 2;

    // 根据球击中挡板的位置改变X方向速度（增加游戏趣味性）
    float hitPos = (ballX - paddleX) / (float)PADDLE_WIDTH;  // 0到1之间
    ballVX = (hitPos - 0.5) * BALL_SPEED * 2;                // -BALL_SPEED 到 +BALL_SPEED

    // 确保Y方向速度不会太小
    if (abs(ballVY) < BALL_SPEED * 0.6) {
      ballVY = (ballVY > 0) ? BALL_SPEED * 0.6 : -BALL_SPEED * 0.6;
    }
  }
}

// 检查球与砖块的碰撞
void Brick::checkBrickCollision() {
  for (int row = 0; row < BRICK_ROWS; row++) {
    for (int col = 0; col < BRICK_COLS; col++) {
      if (bricks[row][col] > 0) {
        int brickX = BRICK_OFFSET_X + col * (BRICK_WIDTH + BRICK_PADDING);
        int brickY = BRICK_OFFSET_Y + row * (BRICK_HEIGHT + BRICK_PADDING);

        // 简单的矩形碰撞检测
        if (ballX + BALL_SIZE / 2 >= brickX && ballX - BALL_SIZE / 2 <= brickX + BRICK_WIDTH && ballY + BALL_SIZE / 2 >= brickY && ballY - BALL_SIZE / 2 <= brickY + BRICK_HEIGHT) {

          // 消除砖块
          bricks[row][col] = 0;
          bricksRemaining--;

          // 增加分数（不同颜色分数不同）
          score += (row + 1) * 10;

          // 判断碰撞方向并反弹
          float ballCenterX = ballX;
          float ballCenterY = ballY;
          float brickCenterX = brickX + BRICK_WIDTH / 2;
          float brickCenterY = brickY + BRICK_HEIGHT / 2;

          float dx = abs(ballCenterX - brickCenterX);
          float dy = abs(ballCenterY - brickCenterY);

          if (dx / BRICK_WIDTH > dy / BRICK_HEIGHT) {
            // 水平碰撞
            ballVX = -ballVX;
          } else {
            // 垂直碰撞
            ballVY = -ballVY;
          }

          return;  // 一次只处理一个砖块碰撞
        }
      }
    }
  }
}

// 重置球到挡板上
void Brick::resetBall() {
  ballX = paddleX + PADDLE_WIDTH / 2;
  ballY = PADDLE_Y - BALL_SIZE - 1;
  ballVX = 0;
  ballVY = 0;
  state = READY;
}

// 检查是否获胜
bool Brick::checkWin() {
  return bricksRemaining <= 0;
}

// 更新游戏状态
void Brick::updateGame() {
  if (state != PLAYING) {
    return;
  }

  moveBall();
  checkBallCollision();
  checkPaddleCollision();
  checkBrickCollision();

  // 检查是否获胜
  if (checkWin()) {
    state = WIN;
  }
}

// ========== 输入处理 ==========

void Brick::handleInput(Keys &keys) {
  keys.kvs_update();

  // 暂停/继续
  if (keys.a.pressed()) {
    if (state == PLAYING) {
      state = PAUSED;
    } else if (state == PAUSED) {
      state = PLAYING;
    }
    delay(200);  // 防抖
  }

  // 在准备状态或游戏中都可以移动挡板
  if (state == READY || state == PLAYING) {
    if (!keys.left.read()) {
      movePaddle(-1);
    } else if (!keys.right.read()) {
      movePaddle(1);
    }
  }

  // 发射球
  if (state == READY && keys.o.pressed()) {
    launchBall();
  }
}

// ========== 主游戏循环 ==========

void Brick::main(Screen &screen, Keys &keys) {
  // 初始化游戏
  initGame();

  // 清屏并设置文本对齐方式
  screen.clearAndLeft();

  // 绘制初始界面
  drawGameArea(screen);
  drawBricks(screen);
  drawPaddle(screen);
  drawBall(screen);
  drawInfo(screen);
  drawReadyMessage(screen);
  screen.drawScreen();

  // 游戏主循环
  while (true) {
    unsigned long currentTime = millis();

    // 处理输入
    handleInput(keys);

    // 检查是否退出
    if (keys.x.pressed()) {
      screen.clearAndCenter();
      return;
    }

    // 根据游戏状态更新
    if (state == PLAYING) {
      // 更新游戏逻辑（控制帧率）
      if (currentTime - lastUpdateTime > 16) {  // 约60fps
        updateGame();
        lastUpdateTime = currentTime;
      }

      // 重绘游戏画面
      screen.spr.fillRect(LEFT_BORDER_X, TOP_BORDER_Y, TFT_WIDTH - 2, TFT_HEIGHT - TOP_BORDER_Y, TFT_BLACK);
      drawBricks(screen);
      drawPaddle(screen);
      drawBall(screen);
      drawInfo(screen);
    } else if (state == READY) {
      // 准备状态
      screen.spr.fillRect(LEFT_BORDER_X, TOP_BORDER_Y, TFT_WIDTH - 2, TFT_HEIGHT - TOP_BORDER_Y, TFT_BLACK);
      drawBricks(screen);
      drawPaddle(screen);
      drawBall(screen);
      drawInfo(screen);
      drawReadyMessage(screen);
    } else if (state == PAUSED) {
      // 暂停状态
      drawPausedMessage(screen);
    } else if (state == GAME_OVER) {
      // 游戏结束
      drawGameOver(screen);
      screen.drawScreen();

      // 等待玩家选择
      while (true) {
        keys.kvs_update();

        if (keys.b.pressed()) {
          // 重新开始
          main(screen, keys);
          return;
        }

        if (keys.x.pressed()) {
          // 退出
          screen.clearAndCenter();
          return;
        }

        delay(10);
      }
    } else if (state == WIN) {
      // 胜利
      drawWin(screen);
      screen.drawScreen();

      // 等待玩家选择
      while (true) {
        keys.kvs_update();

        if (keys.b.pressed()) {
          // 重新开始
          main(screen, keys);
          return;
        }

        if (keys.x.pressed()) {
          // 退出
          screen.clearAndCenter();
          return;
        }

        delay(10);
      }
    }

    // 更新屏幕
    screen.drawScreen();

    delay(10);  // 降低CPU使用率
  }
}
